use {
    crate::base::{
        client::{Address, Client},
        params::{BroadcasthexParams, CreateTransactionParams, GetAccountParams},
        response::{account::Account, account_net::AccountNet, transaction::{ Transaction as Tx, TxId}},
    },
    anychain_core::Transaction,
};

pub async fn get_account(client: &Client, address: &str) -> anyhow::Result<Account> {
    let address = Address::Base58(address.to_string());
    let account_ret = client
        .post("/walletsolidity/getaccount", GetAccountParams::new(address)).await;
    let account = match account_ret {
        Ok(account) => account,
        Err(_) => {
            Account::default()
        }
    };
    Ok(account)
}

pub async fn get_account_net(client: &Client, address: Address) -> anyhow::Result<AccountNet> {
    client
        .post("/wallet/getaccountnet", GetAccountParams::new(address))
        .await
}

pub async fn transfer_coin(
    client: &Client,
    payer: &str,
    from_address_str: &str,
    to_address_str: &str,
    amount: u64,
) -> anyhow::Result<String> {
    let from_address = Address::Base58(from_address_str.to_string());
    let to_address = Address::Base58(to_address_str.to_string());
    let transaction: Tx = client
        .post(
            "/wallet/createtransaction",
            CreateTransactionParams::new(from_address, to_address, amount),
        )
        .await?;
    let tx_raw_hex = transaction.raw_data_hex;
    let tx_raw_data = hex::decode(tx_raw_hex).unwrap();

    let payer_bytes = hex::decode(payer).unwrap();

    let mut tron_tx =
        anychain_tron::transaction::TronTransaction::from_bytes(&tx_raw_data).unwrap();

    let hash = anychain_core::crypto::sha256(&tx_raw_data);
    let message = libsecp256k1::Message::parse(&hash);
    let secret_key = libsecp256k1::SecretKey::parse_slice(&payer_bytes).unwrap();
    let (signature, rec_id) = libsecp256k1::sign(&message, &secret_key);
    let tx_bytes = tron_tx
        .sign(signature.serialize().to_vec(), rec_id.serialize())
        .unwrap();
    let tx_hex = hex::encode(tx_bytes);

    let ret: TxId = client
        .post("wallet/broadcasthex", BroadcasthexParams::new(tx_hex))
        .await?;
    
    Ok(ret.tx_id)
}
